/*
 * Javascript Agile Suite - JasMockTests
 * http://code.google.com/p/jasproject/
 *
 * Copyright (C) 2009 Luke Schafer
 * Licensed under MIT X11 license:
 * http://www.opensource.org/licenses/mit-license.php
 *
 *
 * Test JasMock
 *
 * All tests use a mock with functions like that returned by createMock
 *
 */

Jas.Tests = Jas.Tests || {};

Jas.Tests.JasMock = {
	namespace : "Jas.Tests.JasMock",

	createMock : function()
	{
		return JasMock.create({
			stubOne : function(a) { return a+1; },
			stubTwo : function() { return this.stubOne(1) }
		});
	},

	createMockPrototype : function()
	{
		function mock(){}
		mock.prototype.stubOne = function(a) { return a+1; };
		mock.prototype.stubTwo = function() { return this.stubOne(1) };
		return mock;
	},

	veryifyTestMock : function(mock, checkBehaviour)
	{
		// Check we have an object with the required functions.
		Assert.isNotNull(mock.stubOne);
		Assert.isNotNull(mock.stubTwo);

		// Check the mock functions are bound.
		Assert.isNotNull(mock.stubOne.checkWasCalled);
		Assert.isNotNull(mock.stubOne.checkTookArgs);
		Assert.isNotNull(mock.stubOne.checkReturned);
		Assert.isNotNull(mock.stubTwo.checkWasCalled);

		if (!checkBehaviour) return;

		// Check it works as expected.
		this.testCheckWasCalled(mock);
		this.testCheckTookArgs(mock);
		this.testCheckReturned(mock);
	},

	testCreate : function()
	{
		var mock = this.createMock();
		this.veryifyTestMock(mock, true);
	},

	testFrom : function()
	{
		var mock = JasMock.from(this.createMockPrototype(), {
			stubOne : function(a) { return 2; }
		});

		mock.stubOne(1);
		this.veryifyTestMock(mock, false);
		this.testCheckTookArgs(mock);
		this.testCheckReturned(mock);
	},

	testWrap : function()
	{
		var proto = JasMock.wrap(this.createMockPrototype());
		var mock = new proto();
		this.veryifyTestMock(mock, true);
	},

	testCheckWasCalled : function(mock)
	{
		// If used by other tests, this needs to be the first call.
		mock = mock || this.createMock();

		Assert.isFalse(mock.stubOne.checkWasCalled());
		Assert.areEqual(2, mock.stubTwo());
		Assert.isTrue(mock.stubOne.checkWasCalled());
	},

	testCheckTookArgs : function(mock)
	{
		// Nasty, but reusable.
		if (!mock)
		{
			mock = this.createMock();
			mock.stubTwo();
		}
		
		Assert.isTrue(mock.stubOne.checkTookArgs(1));
	},

	testCheckReturned : function(mock)
	{
		// Nasty, but reusable.
		if (!mock)
		{
			mock = this.createMock();
			mock.stubTwo();
		}
		
		Assert.isTrue(mock.stubOne.checkReturned(2));

	}
};